self.importScripts('/coherentpdf.browser.min.js');

function parsePageRange(rangeString, totalPages) {
  const pages = new Set();
  const parts = rangeString.split(',').map(s => s.trim());

  for (const part of parts) {
    if (part.includes('-')) {
      const [start, end] = part.split('-').map(s => parseInt(s.trim(), 10));
      if (isNaN(start) || isNaN(end)) continue;
      for (let i = Math.max(1, start); i <= Math.min(totalPages, end); i++) {
        pages.add(i);
      }
    } else {
      const pageNum = parseInt(part, 10);
      if (!isNaN(pageNum) && pageNum >= 1 && pageNum <= totalPages) {
        pages.add(pageNum);
      }
    }
  }

  return Array.from(pages).sort((a, b) => a - b);
}

function addAttachmentsToPDFInWorker(pdfBuffer, attachmentBuffers, attachmentNames, attachmentLevel, pageRange) {
  try {
    const uint8Array = new Uint8Array(pdfBuffer);

    let pdf;
    try {
      pdf = coherentpdf.fromMemory(uint8Array, '');
    } catch (error) {
      const errorMsg = error.message || error.toString();

      if (errorMsg.includes('Failed to read PDF') ||
        errorMsg.includes('Could not read object') ||
        errorMsg.includes('No /Root entry') ||
        errorMsg.includes('PDFError')) {
        self.postMessage({
          status: 'error',
          message: 'The PDF file has structural issues and cannot be processed. The file may be corrupted, incomplete, or created with non-standard tools. Please try:\n\n• Opening and re-saving the PDF in another PDF viewer\n• Using a different PDF file\n• Repairing the PDF with a PDF repair tool'
        });
      } else {
        self.postMessage({
          status: 'error',
          message: `Failed to load PDF: ${errorMsg}`
        });
      }
      return;
    }

    const totalPages = coherentpdf.pages(pdf);

    let targetPages = [];
    if (attachmentLevel === 'page') {
      if (!pageRange) {
        self.postMessage({
          status: 'error',
          message: 'Page range is required for page-level attachments.'
        });
        coherentpdf.deletePdf(pdf);
        return;
      }
      targetPages = parsePageRange(pageRange, totalPages);
      if (targetPages.length === 0) {
        self.postMessage({
          status: 'error',
          message: 'Invalid page range specified.'
        });
        coherentpdf.deletePdf(pdf);
        return;
      }
    }

    for (let i = 0; i < attachmentBuffers.length; i++) {
      try {
        const attachmentData = new Uint8Array(attachmentBuffers[i]);
        const attachmentName = attachmentNames[i];

        if (attachmentLevel === 'document') {
          coherentpdf.attachFileFromMemory(attachmentData, attachmentName, pdf);
        } else {
          for (const pageNum of targetPages) {
            coherentpdf.attachFileToPageFromMemory(attachmentData, attachmentName, pdf, pageNum);
          }
        }
      } catch (error) {
        console.warn(`Failed to attach file ${attachmentNames[i]}:`, error);
        self.postMessage({
          status: 'error',
          message: `Failed to attach file ${attachmentNames[i]}: ${error.message || error}`
        });
        coherentpdf.deletePdf(pdf);
        return;
      }
    }

    // Save the modified PDF
    const modifiedBytes = coherentpdf.toMemory(pdf, false, false);
    coherentpdf.deletePdf(pdf);

    const buffer = modifiedBytes.buffer.slice(
      modifiedBytes.byteOffset,
      modifiedBytes.byteOffset + modifiedBytes.byteLength
    );

    self.postMessage({
      status: 'success',
      modifiedPDF: buffer
    }, [buffer]);

  } catch (error) {
    self.postMessage({
      status: 'error',
      message: error instanceof Error
        ? error.message
        : 'Unknown error occurred while adding attachments.'
    });
  }
}

self.onmessage = (e) => {
  if (e.data.command === 'add-attachments') {
    addAttachmentsToPDFInWorker(
      e.data.pdfBuffer,
      e.data.attachmentBuffers,
      e.data.attachmentNames,
      e.data.attachmentLevel || 'document',
      e.data.pageRange || ''
    );
  }
};
